package com.hkts.management.cargo.service.serviceimpl;

import com.alibaba.druid.sql.visitor.functions.Isnull;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hkts.management.cargo.entity.HktsCargo;
import com.hkts.management.cargo.mapper.HktsCargoMapper;
import com.hkts.management.cargo.service.IHktsCargoService;
import com.hkts.management.cargoViewRecord.service.ICargoViewRecordService;
import com.hkts.management.cargoapply.entity.HktsCargoApply;
import com.hkts.management.cargoapply.mapper.HktsCargoApplyMapper;
import com.hkts.management.cargoapply.service.IHktsCargoApplyService;
import com.hkts.management.cargodetail.entity.HktsCargoDetail;
import com.hkts.management.cargodetail.mapper.HktsCargoDetailMapper;
import com.hkts.management.cargodetail.service.IHktsCargoDetailService;
import com.hkts.management.cargolabel.entity.HktsCargoLabel;
import com.hkts.management.cargolabel.service.IHktsCargoLabelService;
import com.hkts.management.common.utils.Result;
import com.hkts.management.common.utils.ResultUtil;
import com.hkts.management.common.utils.SnowFlakeUtil;
import com.hkts.management.common.vo.UserAndRealNameVo;
import com.hkts.management.common.vo.UserBasicInfoVo;
import com.hkts.management.contract.entity.HktsContract;
import com.hkts.management.contract.mapper.HktsContractMapper;
import com.hkts.management.es.EsSearchUtil;
import com.hkts.management.feign.FeignInterface;
import com.hkts.management.feign.FrontInterface;
import com.hkts.management.feign.YbInterface;
import com.hkts.management.loadTime.entity.HktsLoadingTime;
import com.hkts.management.loadTime.service.IHktsLoadingTimeService;
import com.hkts.management.model.DTO.HktsCargoDTO;
import com.hkts.management.model.DTO.HktsCargoTo;
import com.hkts.management.model.DTO.PcCargoDTO;
import com.hkts.management.model.TO.HktsRegionTo;
import com.hkts.management.model.TO.HontUserTo;
import com.hkts.management.model.constants.CargoDetailsVoConstants;
import com.hkts.management.model.constants.CargoListVoConstants;
import com.hkts.management.model.constants.OrderVoConstants;
import com.hkts.management.model.enums.OrderStatusEnum;
import com.hkts.management.model.enums.OrderTypeEnum;
import com.hkts.management.model.result.ResultAreaPlace;
import com.hkts.management.model.result.ResultData;
import com.hkts.management.model.result.ResultDataType;
import com.hkts.management.order.entity.HktsOrder;
import com.hkts.management.order.mapper.HktsOrderMapper;
import com.hkts.management.order.service.IHktsOrderService;
import com.hkts.management.properties.HistoryProperties;
import com.hkts.management.returnfee.service.IHktsReturnFailService;
import com.hkts.management.utils.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hkts.management.cargolabel.mapper.HktsCargoLabelMapper;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.hkts.management.es.constants.EsCargoConstants.*;
import static com.hkts.management.es.constants.EsCargoConstants.CARGO_ORDER_INDEX;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hml
 * @since 2021-04-22
 */
@Service
@Slf4j
@Transactional
public class HktsCargoServiceImpl extends ServiceImpl<HktsCargoMapper, HktsCargo> implements IHktsCargoService {


    @Autowired
    private HktsCargoMapper hktsCargoMapper;

    @Autowired
    private HktsCargoDetailMapper cargoDetailMapper;

    @Autowired
    private HktsCargoLabelMapper labelMapper;

    @Autowired
    private IHktsCargoLabelService labelService;

    @Autowired
    private IHktsCargoApplyService applyService;

    @Autowired
    private IHktsOrderService orderService;

    @Autowired
    private HktsOrderMapper orderMapper;

    @Autowired
    private HktsContractMapper contractMapper;

    @Autowired
    private HktsCargoApplyMapper cargoApplyMapper;

    @Autowired
    public IHktsReturnFailService iHktsReturnFailService;

    @Autowired
    private ICargoViewRecordService cargoViewRecordService;

    @Autowired
    private FeignInterface feignInterface;

    @Autowired
    private FrontInterface frontInterface;
    @Autowired
    private YbInterface ybInterface;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RegionConverUtil regionConverUtil;
    @Autowired
    private IHktsLoadingTimeService loadingTimeService;
    @Autowired
    private IHktsCargoDetailService cargoDetailService;
    @Autowired
    private EsSearchUtil esSearchUtil;

    @Override
    public IPage<HktsCargo> selectPage(Page<HktsCargo> page, HktsCargo hktsCargo) {
        QueryWrapper<HktsCargo> query = Wrappers.query();
        QueryWrapper<HktsCargo> entityWrapper = getEntityWrapper(query, hktsCargo);
        return hktsCargoMapper.selectPage(page, entityWrapper);
    }


    @Override
    public List<HktsCargo> selectList(HktsCargo hktsCargo) {
        QueryWrapper<HktsCargo> query = Wrappers.query();
        QueryWrapper<HktsCargo> entityWrapper = getEntityWrapper(query, hktsCargo);
        return hktsCargoMapper.selectList(entityWrapper);
    }


    /**
     * 公共查询条件
     *
     * @param entityWrapper
     * @return
     */
    public QueryWrapper<HktsCargo> getEntityWrapper(QueryWrapper<HktsCargo> entityWrapper, HktsCargo hktsCargo) {
        //条件拼接
        if (StringUtils.isNotBlank(hktsCargo.getCargoName())) {
            entityWrapper.lambda().like(HktsCargo::getCargoName, hktsCargo.getCargoName());
        }
        return entityWrapper;
    }

    /**
     * 货源列表(小程序)
     *
     * @param page
     * @param hktsCargoDTO
     * @return
     */
    @Override
    public IPage<ResultData> getHktsCargoPageListOnPhone(Page page, HktsCargoDTO hktsCargoDTO) {
        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        QueryWrapper<HktsCargo> query = Wrappers.query();
        //条件
        if (hktsCargoDTO != null) {
            query.lambda().eq(!"".equals(hontUserTo.getId()), HktsCargo::getUserId, hontUserTo.getId())
                    .eq(!"".equals(hktsCargoDTO.getCargoStatus()), HktsCargo::getCargoStatus, hktsCargoDTO.getCargoStatus())
                    .apply(hktsCargoDTO.getStartPlace() != null,
                            "start_area LIKE '" + getRegion(hktsCargoDTO.getStartPlace()) + "%'")
                    .apply(hktsCargoDTO.getEndPlace() != null,
                            "end_area LIKE '" + getRegion(hktsCargoDTO.getEndPlace()) + "%'")
                    .apply(!"".equals(hktsCargoDTO.getStartDate()),
                            "date_format (push_time,'%Y-%m-%d') >= date_format('" + hktsCargoDTO.getStartDate() + "','%Y-%m-%d')")
                    .apply(!"".equals(hktsCargoDTO.getEndDate()),
                            "date_format (push_time,'%Y-%m-%d') <= date_format('" + hktsCargoDTO.getEndDate() + "','%Y-%m-%d')")
                    .orderByDesc(HktsCargo::getPushTime);
        }
        IPage page1 = hktsCargoMapper.selectPage(page, query);
        List<HktsCargo> list = page1.getRecords();
        List<ResultData> resultDate = list.stream().map(this::assemblyCargoData).collect(Collectors.toList());
        page1.setRecords(resultDate);
        return page1;
    }

    private String getRegion(String place) {
        if ("".equals(place) || place == null) {
            return "";
        }
        HktsRegionTo result = frontInterface.hktsRegionGetByCode(place).getResult();
        if (result.getRegionType().equals("1")) {
            return place.substring(0, place.length() - 4);
        } else if (result.getRegionType().equals("2")) {
            return place.substring(0, place.length() - 2);
        } else {
            return place;
        }
    }

    private ResultData assemblyCargoData(HktsCargo hktsCargo) {
        log.info("返回数据{}", hktsCargo);

        ResultData hktsCargoVo = new ResultData();
        hktsCargoVo.setId(hktsCargo.getId());
        hktsCargoVo.setStatus(hktsCargo.getCargoStatus());
        hktsCargoVo = assemblyAreaPlace(hktsCargo, hktsCargoVo);

        //组装数据信息
        Map<String, Object> totalinfo = new HashMap<>();
        //查询货源详情
        HktsCargoDetail cargoDetail=cargoDetailService.getHktsCargoDetailByCargoId(hktsCargo.getId());
        totalinfo.put(CargoListVoConstants.ESTIMATE_DISTANCE, cargoDetail.getEstimateDistance());
        totalinfo.put(CargoListVoConstants.ESTIMATE_DISTANCE_UNIT, cargoDetail.getEstimateDistanceUnit());

        totalinfo.put(CargoListVoConstants.TRANSPORTPRICE, hktsCargo.getTransportPrice());
        totalinfo.put(CargoListVoConstants.PUSHTIME, RelativeDateFormat.format(Date.from(hktsCargo.getPushTime().atZone(ZoneId.systemDefault()).toInstant())));
        totalinfo.put(CargoListVoConstants.CARGOtOTAL, hktsCargo.getCargoTotal());
        totalinfo.put(CargoListVoConstants.CARGORESIDUAL, hktsCargo.getCargoResidual());
        totalinfo.put(CargoListVoConstants.CARGORESIDUALUNIT, hktsCargo.getCargoUnit());
        totalinfo.put(CargoDetailsVoConstants.DEPOSIT,cargoDetail.getDeposit());
        //报名人数
        totalinfo.put("applyTotal", orderService.selectCount(hktsCargo.getId()));
        // TODO 已查看人数统计
        int viewRecordCount = cargoViewRecordService.getViewRecordCount(hktsCargo.getId());
        totalinfo.put("viewRecordCount", viewRecordCount);
        totalinfo.put(CargoListVoConstants.CARTYPE, labelService.getCargoLanelByCargoId(hktsCargo.getId(), 3));
        totalinfo.put(CargoListVoConstants.CARLENGTH, labelService.getCargoLanelByCargoId(hktsCargo.getId(), 4));
        totalinfo.put("appoint",hktsCargo.getAppoint());
        totalinfo.put(CargoListVoConstants.CARLENGTHUNIT,"米");
        List<HktsLoadingTime> loadingTimes=loadingTimeService.getLoadTimeByCargoId(hktsCargo.getId());
        totalinfo.put(CargoListVoConstants.CARGONAME,hktsCargo.getCargoName());
        totalinfo.put(CargoListVoConstants.PACKMODE,StringUtils.strip(labelService.getCargoLanelByCargoId(hktsCargo.getId(), 1).toString(), "[]").replace(" ", ""));
        totalinfo.put(CargoListVoConstants.LOADINGTIME,loadingTimes);
        totalinfo.put(CargoListVoConstants.LOADINGMODE,StringUtils.strip(labelService.getCargoLanelByCargoId(hktsCargo.getId(), 2).toString(), "[]").replace(" ", ""));
        hktsCargoVo.setTotalinfo(totalinfo);
        //组装排序信息
        List<ResultDataType> list=new ArrayList<>();
        ResultDataType carGolabel=new ResultDataType();
        carGolabel.setKey(CargoListVoConstants.CARGOINFO);
        carGolabel.setValue(Arrays.asList(CargoListVoConstants.CARGONAME,CargoListVoConstants.PACKMODE,CargoListVoConstants.LOADINGTIME,CargoListVoConstants.LOADINGMODE,CargoListVoConstants.CARTYPE,CargoListVoConstants.CARLENGTH));
        list.add(carGolabel);
        hktsCargoVo.setGoodsinfo(list);
        return hktsCargoVo;
    }


    public ResultData assemblyAreaPlace(HktsCargo hktsCargo, ResultData resultData) {
        //组装起始地
        String startAreaStr = hktsCargo.getStartArea();
        String endAreaStr = hktsCargo.getEndArea();
        ResultAreaPlace startPlace = new ResultAreaPlace();


        startPlace.setAddressCode(startAreaStr);
        startPlace.setAddress(hktsCargo.getStartAddressDetail());
        startPlace.setTitle(hktsCargo.getStartTitle());
        Integer reginCodeStart = Integer.valueOf(hktsCargo.getStartArea());
        startPlace = regionConverUtil.regionCover(reginCodeStart, startPlace);

        List<HktsLoadingTime> loadingTimes=loadingTimeService.getLoadTimeByCargoId(hktsCargo.getId());
        startPlace.setLoadingTimes(loadingTimes);
        startPlace.setLatitude(hktsCargo.getStartLat());
        startPlace.setLongitude(hktsCargo.getStartLon());
        ResultAreaPlace endPlace = new ResultAreaPlace();
        endPlace.setAddressCode(endAreaStr);
        endPlace.setAddress(hktsCargo.getEndAddressDetail());
        endPlace.setTitle(hktsCargo.getEndTitle());
        endPlace.setLatitude(hktsCargo.getEndLat());
        endPlace.setLongitude(hktsCargo.getEndLon());
        Integer reginCodeEnd = Integer.valueOf(hktsCargo.getEndArea());
        endPlace = regionConverUtil.regionCover(reginCodeEnd, endPlace);

        resultData.setStartPlace(startPlace);
        resultData.setEndPlace(endPlace);
        return resultData;
    }

    /**
     * 详细信息
     *
     * @param cargoId
     * @return
     */
    @Override
    public ResultData getCargoDetailById(String cargoId) {


        HktsCargo hktsCargo = hktsCargoMapper.selectById(cargoId);
        ResultData resultData = new ResultData();
        resultData.setId(cargoId);
        resultData.setStatus(hktsCargo.getCargoStatus());
        resultData = assemblyAreaPlace(hktsCargo, resultData);
        if (hktsCargo == null) {
            return new ResultData();
        }
        QueryWrapper<HktsCargoDetail> query = Wrappers.query();
        query.lambda().eq(HktsCargoDetail::getCargoId, cargoId);
        HktsCargoDetail hktsCargoDetail = cargoDetailMapper.selectOne(query);

        List<ResultDataType> list = new ArrayList<>();
        ResultDataType carinfo = new ResultDataType();
        carinfo.setKey(CargoListVoConstants.CARINFO);
        carinfo.setName("车辆");
        carinfo.setValue(Arrays.asList(CargoListVoConstants.CARLENGTH, CargoListVoConstants.CARTYPE));
        ResultDataType carGolabel = new ResultDataType();
        carGolabel.setKey(CargoListVoConstants.CARGOINFO);
        carGolabel.setName("货物");
        carGolabel.setValue(Arrays.asList(CargoListVoConstants.CARGONAME,  CargoListVoConstants.PACKMODE,CargoListVoConstants.CARGOtOTAL));
        ResultDataType remark = new ResultDataType();
        remark.setKey(CargoDetailsVoConstants.REMARK);
        remark.setName("特殊要求");
        remark.setValue(Arrays.asList(CargoDetailsVoConstants.REMARK));
        list.add(carinfo);
        list.add(carGolabel);
        list.add(remark);
        resultData.setGoodsinfo(list);


        Map<String, Object> totalinfo = new HashMap<>();
        QueryWrapper<HktsCargoDetail> detailQuery = Wrappers.query();
        detailQuery.lambda().eq(HktsCargoDetail::getCargoId, cargoId);
        HktsCargoDetail cargoDetail = cargoDetailMapper.selectOne(detailQuery);
        totalinfo.put("distance", cargoDetail.getEstimateDistance());
        totalinfo.put("distanceUnit", "公里");
        int viewRecordCount = cargoViewRecordService.getViewRecordCount(cargoId);
        totalinfo.put("viewRecordCount", viewRecordCount);
        totalinfo.put("surplus", hktsCargo.getCargoResidual());
        totalinfo.put("startCode",frontInterface.getRegionCode(resultData.getStartPlace().getAddressCode()).getResult());
        totalinfo.put("endCode",frontInterface.getRegionCode(resultData.getEndPlace().getAddressCode()).getResult());
        totalinfo.put(CargoListVoConstants.CARLENGTH, labelService.getCargoLanelByCargoId(cargoId, 4));
        totalinfo.put(CargoListVoConstants.CARLENGTHUNIT, "米");
        totalinfo.put(CargoListVoConstants.CARTYPE, labelService.getCargoLanelByCargoId(cargoId, 3));
        totalinfo.put("cargoTotalUnit", hktsCargo.getCargoUnit());
        totalinfo.put(CargoListVoConstants.PACKMODE, labelService.getCargoLanelByCargoId(cargoId, 1));
        totalinfo.put(CargoListVoConstants.CARGOTYPE, labelService.getCargoLanelByCargoId(cargoId, 0));
        totalinfo.put(CargoDetailsVoConstants.REMARK, hktsCargoDetail.getRemark());

        totalinfo.put(CargoListVoConstants.CARGOtOTAL, hktsCargo.getCargoTotal());
        totalinfo.put(CargoDetailsVoConstants.DEPOSIT,hktsCargoDetail.getDeposit());
        totalinfo.put(CargoListVoConstants.LOADINGMODE, labelService.getCargoLanelByCargoId(cargoId, 2));
        List<HktsLoadingTime> loadTimeByCargoId = loadingTimeService.getLoadTimeByCargoId(hktsCargo.getId());
        totalinfo.put(CargoListVoConstants.LOADINGTIME, loadTimeByCargoId);
        totalinfo.put(CargoListVoConstants.CARGONAME,hktsCargo.getCargoName());
        totalinfo.put("cargoTypeId",hktsCargo.getCargoType());
        HktsCargoApply apply = new HktsCargoApply();
        apply.setCargoId(hktsCargo.getId());
        totalinfo.put(CargoDetailsVoConstants.APPLY, applyService.selectCount(apply));
        totalinfo.put(CargoListVoConstants.TRANSPORTPRICE, hktsCargo.getTransportPrice());
        totalinfo.put("is_receipt", hktsCargo.getIsReceipt());
        totalinfo.put("appoint",hktsCargo.getAppoint());
        totalinfo.put("loadingTimeTo",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(loadTimeByCargoId.get(loadTimeByCargoId.size()-1).getLoadingStartTime()));
        totalinfo.put("createTime",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(hktsCargo.getPushTime()));
        Map<String, Object> orderData = getOrderData(cargoId);
        totalinfo.put("orderData",orderData);
        Result<UserBasicInfoVo> userBasicInfoVoByMobile = feignInterface.getUserBasicInfoVoByMobile(hktsCargo.getTelphone());
        resultData.setUserInfo(userBasicInfoVoByMobile.getResult());
        resultData.setTotalinfo(totalinfo);
        return resultData;
    }


    @Override
    public ResultData getCargoDetailById(String id,String lat,String lon) {
        HktsCargo hktsCargo=hktsCargoMapper.selectById(id);
        QueryWrapper<HktsCargoDetail> query = Wrappers.query();
        query.lambda().eq(HktsCargoDetail::getCargoId,id);
        HktsCargoDetail hktsCargoDetail=cargoDetailMapper.selectOne(query);
        if (!lat.isEmpty()){
            String loadingLatAndLon=hktsCargo.getStartLon().toString()+","+hktsCargo.getStartLat().toString();
            String latAndLon=lon+","+lat;
            Long distance= AddressUtils.getDistance(latAndLon,loadingLatAndLon);
            return assemblyCargoDetailData(hktsCargo,hktsCargoDetail,distance);
        }

//        assemblyCargoDetailData(hktsCargo,hktsCargoDetail,distance);
        return assemblyCargoDetailData(hktsCargo,hktsCargoDetail,null);
    }
    private ResultData assemblyCargoDetailData( HktsCargo hktsCargo,HktsCargoDetail hktsCargoDetail,Long distance){

        ResultData resultData=new ResultData();
        resultData=assemblyAreaPlace(hktsCargo,resultData);
        resultData.setId(hktsCargo.getId());
        //组装数据信息
        Map<String ,Object> totalinfo=new HashMap<>();
        totalinfo.put(CargoListVoConstants.CARGOTYPE,labelService.getCargoLanelByCargoId(hktsCargo.getId(),0));
        totalinfo.put(CargoListVoConstants.PACKMODE,labelService.getCargoLanelByCargoId(hktsCargo.getId(),1));
        totalinfo.put(CargoListVoConstants.LOADINGMODE,labelService.getCargoLanelByCargoId(hktsCargo.getId(),2));
        totalinfo.put(CargoListVoConstants.CARTYPE,labelService.getCargoLanelByCargoId(hktsCargo.getId(),3));
        totalinfo.put(CargoListVoConstants.CARLENGTH,labelService.getCargoLanelByCargoId(hktsCargo.getId(),4));
        totalinfo.put(CargoListVoConstants.CARLENGTHUNIT,"米");
        totalinfo.put(CargoListVoConstants.TRANSPORTPRICE,hktsCargo.getTransportPrice());
        totalinfo.put(CargoListVoConstants.PUSHTIME,hktsCargo.getPushTime());
        totalinfo.put(CargoListVoConstants.CARGOtOTAL,hktsCargo.getCargoTotal());
        totalinfo.put(CargoListVoConstants.CARGORESIDUAL,hktsCargo.getCargoResidual());
        totalinfo.put(CargoListVoConstants.CARGORESIDUALUNIT,hktsCargo.getCargoUnit());

        totalinfo.put(CargoDetailsVoConstants.PHONE,hktsCargo.getTelphone().split(","));
        totalinfo.put(CargoDetailsVoConstants.ESTIMATEdISTANCE,hktsCargoDetail.getEstimateDistance());
//        totalinfo.put(CargoDetailsVoConstants.ESTIMATEdISTANCEUNIT,hktsCargoDetail.getEstimateDistanceUnit());
        totalinfo.put(CargoDetailsVoConstants.REMARK,hktsCargoDetail.getRemark());
        totalinfo.put(CargoDetailsVoConstants.DEPOSIT,hktsCargoDetail.getDeposit());
        //组装报名人数
        HktsCargoApply apply=new HktsCargoApply();
        apply.setCargoId(hktsCargo.getId());
        totalinfo.put(CargoDetailsVoConstants.APPLY,applyService.selectCount(apply));

        //装货时间
//        totalinfo.put(CargoListVoConstants.LOADINGDATE,resultData.getStartPlace().getDate());
//        totalinfo.put(CargoListVoConstants.LOADINGTIME,resultData.getStartPlace().getTime());
        totalinfo.put(CargoListVoConstants.LOADINGTIME, loadingTimeService.getLoadTimeByCargoId(hktsCargo.getId()));

        if (distance == null){
            totalinfo.put(CargoListVoConstants.LOADINGDISTANCE,0);
        }else {
            totalinfo.put(CargoListVoConstants.LOADINGDISTANCE,distance);
        }
//        totalinfo.put(CargoListVoConstants.LOADINGDISTANCEUNIT,"m");
        resultData.setTotalinfo(totalinfo);
        //组装排序信息
        List<ResultDataType> list=new ArrayList<>();
        ResultDataType carinfo=new ResultDataType();
        carinfo.setKey(CargoListVoConstants.CARINFO);
        carinfo.setName("车辆");
        carinfo.setValue(Arrays.asList(CargoListVoConstants.CARLENGTH,CargoListVoConstants.CARTYPE));
        ResultDataType carGolabel=new ResultDataType();
        carGolabel.setKey(CargoListVoConstants.CARGOINFO);
        carGolabel.setName("货物");
        carGolabel.setValue(Arrays.asList(CargoListVoConstants.CARGOTYPE,CargoListVoConstants.PACKMODE,CargoListVoConstants.CARGORESIDUAL));
        ResultDataType remark=new ResultDataType();
        remark.setKey(CargoDetailsVoConstants.REMARK);
        remark.setName("特殊要求");
        remark.setValue(Arrays.asList(CargoDetailsVoConstants.REMARK));
        list.add(carinfo);
        list.add(carGolabel);
        list.add(remark);
        resultData.setGoodsinfo(list);

        log.info("货源详情{}",resultData);
        return resultData;
    }


    public IPage<Map<String, Object>> getOrdersPageByApply(Page page, String cargoId) {
        QueryWrapper<HktsOrder> Query = Wrappers.query();
        Query.lambda().eq(HktsOrder::getCargoId, cargoId)
                .orderByDesc(HktsOrder::getCreateTime);
        Page page1 = orderMapper.selectPage(page, Query);
        List<HktsOrder> list = page1.getRecords();
        List<Map<String, Object>> result = list.stream().map(t -> resultOrderPageList(t)).collect(Collectors.toList());
        page1.setRecords(result);
        return page1;
    }

    public Map<String, Object> resultOrderPageList(HktsOrder hktsOrder){

        Map<String, Object> resultMap = new HashMap<>();
        Result<UserAndRealNameVo> driverInfoByUserId = frontInterface.getDriverInfoByUserId(hktsOrder.getDriverId());
        //用户信息
        QueryWrapper<HktsContract> Query = Wrappers.query();
        Query.lambda().eq(HktsContract::getOrderId, hktsOrder.getId());
        HktsContract hktsContract = contractMapper.selectOne(Query);
        if (driverInfoByUserId != null) {
            if (hktsOrder.getOrderStatus().getValue() == 2 || hktsOrder.getOrderStatus().getValue() == 3 || hktsOrder.getOrderStatus().getValue() == 4){
                UserAndRealNameVo result = driverInfoByUserId.getResult();
                result.setCarCode(hktsContract.getCarrierPlate());
                resultMap.put("driverInfo", result);
            }else {
                resultMap.put("driverInfo", driverInfoByUserId.getResult());
            }

        } else {
            resultMap.put("driverInfo", null);
        }
        //订单状态
        resultMap.put("orderId", hktsOrder.getId());
        resultMap.put("orderStatus", hktsOrder.getShipperOrderStatus());
        //HktsCargoApply cargoApplyByCargoIdAndDriver = applyService.getCargoApplyByCargoIdAndDriver(hktsOrder.getCargoId(), hktsOrder.getDriverId());
        QueryWrapper<HktsCargoApply> query = Wrappers.query();
        query.lambda().eq(HktsCargoApply::getId,hktsOrder.getApplyId());
        HktsCargoApply cargoApplyByCargoIdAndDriver = cargoApplyMapper.selectOne(query);
        //定金状态
        if (cargoApplyByCargoIdAndDriver != null) {
            resultMap.put("depositStatus", cargoApplyByCargoIdAndDriver.getDepositStatus());
            resultMap.put("loadWeight", cargoApplyByCargoIdAndDriver.getLoadWeight());
            resultMap.put("checkStatus", cargoApplyByCargoIdAndDriver.getCheckStatus());
            resultMap.put("pay_order",cargoApplyByCargoIdAndDriver.getPayOrder());
        } else {
            resultMap.put("depositStatus", 0);
        }
        return resultMap;
    }
    public IPage<Map<String, Object>> getOrdersPageByApplyPc(Page page, String cargoId,String checkStatus) {
        QueryWrapper<HktsCargoApply> Query = Wrappers.query();
        Query.lambda().eq(HktsCargoApply::getCargoId, cargoId).eq(!checkStatus.isEmpty() && !checkStatus.equals("5"),HktsCargoApply::getCheckStatus,checkStatus)
                .orderByDesc(HktsCargoApply::getCreateTime);
        Page page1 = cargoApplyMapper.selectPage(page, Query);
        List<HktsCargoApply> list = page1.getRecords();
        List<Map<String, Object>> result = list.stream().map(t -> resultOrderPageListPc(t)).collect(Collectors.toList());
        for (int i = 0; i < result.size(); i++) {
            result.get(i).put("serialnumber",page1.getCurrent() * page1.getSize() - page1.getSize() + i + 1);
        }
        page1.setRecords(result);
        return page1;
    }
    public Map<String, Object> resultOrderPageListPc(HktsCargoApply cargoApply){

        Map<String, Object> resultMap = new HashMap<>();
        Result<UserAndRealNameVo> driverInfoByUserId = frontInterface.getDriverInfoByUserId(cargoApply.getDriverId());
        //用户信息
        if (driverInfoByUserId != null) {
            resultMap.put("driverInfo", driverInfoByUserId.getResult());
        } else {
            resultMap.put("driverInfo", null);
        }
        QueryWrapper<HktsOrder> Query = Wrappers.query();
        Query.lambda().eq(HktsOrder::getApplyId, cargoApply.getId());
        HktsOrder hktsOrder = orderMapper.selectOne(Query);
        //定金状态
        resultMap.put("depositStatus", cargoApply.getDepositStatus());
        resultMap.put("loadWeight", cargoApply.getLoadWeight());
        resultMap.put("checkStatus", cargoApply.getCheckStatus());
        resultMap.put("pay_order",cargoApply.getPayOrder());
        resultMap.put("deposit",cargoApply.getDeposit());
        resultMap.put("reviewers",cargoApply.getReviewers());
        resultMap.put("checkTime",cargoApply.getCheckTime());
        resultMap.put("orderId",hktsOrder.getId());
        if (cargoApply.getCreateTime() != null){
            resultMap.put("createTime",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(cargoApply.getCreateTime()));
        }else {
            resultMap.put("createTime","");
        }
        if (driverInfoByUserId.getResult() != null) {
            resultMap.put("type_length", driverInfoByUserId.getResult().getEhicleType() + "/" + driverInfoByUserId.getResult().getVehicleLength() + "米");
            resultMap.put("approvalStatus",driverInfoByUserId.getResult().getApproval());
            if (driverInfoByUserId.getResult().getLoginTime() != null){
                try {
                    String dayNum = getDayNum(driverInfoByUserId.getResult().getApproval(), Date.from(driverInfoByUserId.getResult().getLoginTime().atZone(ZoneId.systemDefault()).toInstant()));
                    resultMap.put("approval", dayNum);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }else {
                resultMap.put("approval", "");
            }
        } else {
            resultMap.put("type_length", "");
            resultMap.put("approval", "");
            resultMap.put("approvalStatus","");
        }
        return resultMap;
    }
    public String getDayNum(String approval, Date time ) throws ParseException {
        switch (approval)
        {
            case "1":
                approval="未认证";
                break;
            case "2":
                approval="已认证";
                break;
            case "3":
                approval="已提交待认证";
                break;
            case "4":
                approval="认证失败";
                break;
            default:
                approval="未认证";
        }
        if(approval.equals("已认证")&&time!=null){
            int i = daysBetween(time);
            approval=approval+"  "+ i+"天";
        }
        return  approval;
    }

    public  int daysBetween(Date smdate) throws ParseException
    {
        Date bdate=new Date();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        smdate=sdf.parse(sdf.format(smdate));
        bdate=sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }


    /**
     * 发布货源
     *
     * @param hktsCargoTo
     */
    @Override
    public Result<HktsCargo> saveCargoAndLabelAndDetail(HktsCargoTo hktsCargoTo) {
        BigDecimal zero = new BigDecimal (1);
        if (hktsCargoTo.getCargoTotal().compareTo(zero) == -1){
            return ResultUtil.error("请填写正确吨数！");
        }
        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        String cargoId=String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
        if(hktsCargoTo.getLoadingTime()==null||hktsCargoTo.getLoadingTime().size()==0){
            return ResultUtil.error("发货时间不能为空");
        }
        Result<Object> result=  loadingTimeService.addLoadTime(cargoId,hktsCargoTo.getLoadingTime());
        if(!result.isSuccess()){
            return ResultUtil.error(result.getMessage());
        }
        HktsCargo hktsCargo = new HktsCargo();
        hktsCargo.setUserId(hontUserTo.getId());
        hktsCargo.setId(cargoId);
        if (!hktsCargoTo.getCargoId().isEmpty()) {
            return updateCargoAndLabelAndDetail(hktsCargoTo);
        }
        String startAreaStr = hktsCargoTo.getStartArea();
        String endAreaStr = hktsCargoTo.getEndArea();

        ResultAreaPlace startPlace = new ResultAreaPlace();
        startPlace.setAddressCode(startAreaStr);
        startPlace.setAddress(hktsCargoTo.getStartAddress());
        Integer reginCodeStart = Integer.valueOf(startAreaStr);
        startPlace = regionConverUtil.regionCover(reginCodeStart, startPlace);
        String startArea = startPlace.getProvice() + startPlace.getCity() + startPlace.getCounty();

        ResultAreaPlace endPlace = new ResultAreaPlace();
        endPlace.setAddressCode(endAreaStr);
        endPlace.setAddress(hktsCargoTo.getEndAddress());
        Integer reginCodeEnd = Integer.valueOf(endAreaStr);
        endPlace = regionConverUtil.regionCover(reginCodeEnd, endPlace);
        String endArea = endPlace.getProvice() + endPlace.getCity() + endPlace.getCounty();
        /**
         * 装货地点
         */
        if (StringUtils.isBlank(hktsCargoTo.getStartAddress()) && StringUtils.isBlank(hktsCargoTo.getEndAddress())){
            return ResultUtil.error("装卸货详细地址不能为空");
        }
        hktsCargo.setStartArea(startAreaStr);
        hktsCargo.setStartAddressDetail(hktsCargoTo.getStartAddress());
        hktsCargo.setStartTitle(hktsCargoTo.getStartTitle());
        String lonLat = AddressUtils.getLonLat(startArea + hktsCargoTo.getStartAddress());
        String lon = lonLat.substring(0, lonLat.indexOf(","));
        String lat = lonLat.substring(lon.length() + 1, lonLat.length());

        BigDecimal lonto = StringUtil.getbd(lon);
        BigDecimal latto = StringUtil.getbd(lat);
        hktsCargo.setStartLat(latto);
        hktsCargo.setStartLon(lonto);
        /**
         * 卸货地点
         */

        hktsCargo.setEndArea(endAreaStr);
        hktsCargo.setEndAddressDetail(hktsCargoTo.getEndAddress());
        hktsCargo.setEndTitle(hktsCargoTo.getEndTitle());
        /*if (AddressUtils.getLonLat(hktsCargoTo.getEndAddress()) == null){
            return ResultUtil.error("请选择正确的卸货地");
        }*/
        String endlonLat = AddressUtils.getLonLat(endArea + hktsCargoTo.getEndAddress());
        String endlon = endlonLat.substring(0, endlonLat.indexOf(","));
        String endlat = endlonLat.substring(endlon.length() + 1, endlonLat.length());
        BigDecimal endlonto = StringUtil.getbd(endlon);
        BigDecimal endlatto = StringUtil.getbd(endlat);
        hktsCargo.setEndLat(endlatto);
        hktsCargo.setEndLon(endlonto);
        String lonLatT = AddressUtils.getLonLat(hktsCargoTo.getStartAddress());
        String endlonLatT = AddressUtils.getLonLat(hktsCargoTo.getEndAddress());
        if (StringUtils.isBlank(lonLatT) && StringUtils.isBlank(endlonLatT)){
            return ResultUtil.error("请填写正确的装卸货地址");
        }

        /**
         * 重量、装货时间、是否邮寄回单、价格、发布时间、单位、剩余重量、用户姓名、电话、状态
         */

        BigDecimal transportPrice = StringUtil.getbd(hktsCargoTo.getTransportPrice());
//        LocalDateTime startTime = StringUtil.getldt(hktsCargoTo.getStartTime() + " " + hktsCargoTo.getStartTimeHours());
//        LocalDateTime endTime = StringUtil.getldt(hktsCargoTo.getEndTime() + " " + hktsCargoTo.getEndTimeHours());
//        hktsCargo.setLoadingStartTime(startTime);
//        hktsCargo.setLoadingEndTime(endTime);
        hktsCargo.setCargoTotal(hktsCargoTo.getCargoTotal());
        hktsCargo.setIsReceipt(Integer.parseInt(hktsCargoTo.getIsReceipt()));
        hktsCargo.setTransportPrice(transportPrice);

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String transformDate = simpleDateFormat.format(new Date());
        LocalDateTime pushTime = StringUtil.getldt(transformDate);
        hktsCargo.setPushTime(pushTime);
        hktsCargo.setCargoUnit("吨");
        hktsCargo.setCargoResidual(hktsCargoTo.getCargoTotal());
        hktsCargo.setCargoStatus(0);
        hktsCargo.setUsername(hontUserTo.getNickName());
        hktsCargo.setTelphone(hontUserTo.getMobile());
        hktsCargo.setCompanyCode(hontUserTo.getCompanyId());
        hktsCargo.setYbOrderCode(hktsCargoTo.getYbOrderCode());
        hktsCargo.setOrderType(hktsCargoTo.getOrderType());
        if (StringUtils.isBlank(hktsCargoTo.getCargoType())){
            return ResultUtil.error("货物类型为空");
        }else {
            hktsCargo.setCargoType(hktsCargoTo.getCargoType());
        }
        if (hktsCargoTo.getCargoName().isEmpty()){
            return ResultUtil.error("请输入货物名称！");
        }
        hktsCargo.setCargoName(hktsCargoTo.getCargoName());
        if (hktsCargoTo.getAppoint() != null){
            hktsCargo.setAppoint(hktsCargoTo.getAppoint());
        }else {
            hktsCargo.setAppoint(0);
        }
        hktsCargoMapper.insert(hktsCargo);

        /**
         * 货物信息
         */
        if (!hktsCargoTo.getLabelinfo().isEmpty()) {
            for (int i = 0; i < hktsCargoTo.getLabelinfo().size(); i++) {
                Integer type = hktsCargoTo.getLabelinfo().get(i).getType();
                List<String> values = hktsCargoTo.getLabelinfo().get(i).getValues();


                for (int j = 0; j < values.size(); j++) {
                    HktsCargoLabel cargoLabel = new HktsCargoLabel();
                    cargoLabel.setId(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
                    cargoLabel.setCargoId(cargoId);
                    cargoLabel.setLabelType(type);
                    cargoLabel.setLabelName(values.get(j));
                    if (type == 4) {
                        cargoLabel.setLabelUnit("米");
                    }
                    cargoLabel.setCreateTime(LocalDateTime.now());
                    labelMapper.insert(cargoLabel);
                }
            }
        }
        HktsCargoDetail cargoDetail = new HktsCargoDetail();
        cargoDetail.setId(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
        cargoDetail.setCargoId(cargoId);
        cargoDetail.setRemark(hktsCargoTo.getRemark());
        cargoDetail.setDeposit(hktsCargoTo.getDeposit());
        cargoDetail.setCreateTime(LocalDateTime.now());
        if(hktsCargoTo.getDistance() == null ){
            BigDecimal distance = getDistance(startArea + hktsCargoTo.getStartAddress(), endArea + hktsCargoTo.getEndAddress());
            cargoDetail.setEstimateDistance(distance);
        }else {
            cargoDetail.setEstimateDistance(hktsCargoTo.getDistance());
        }
        cargoDetailMapper.insert(cargoDetail);
        Map<String, String> loadingHistory = new HashMap<>();
        loadingHistory.put("startArea", startArea);
        loadingHistory.put("startAddressDetail", hktsCargo.getStartAddressDetail());
        loadingHistory.put("regionCode", startAreaStr);
        loadingHistory.put("startTitle", hktsCargo.getStartTitle());
        saveLoadingHistory(loadingHistory);
        Map<String, String> unloadHistory = new HashMap<>();
        unloadHistory.put("endArea", endArea);
        unloadHistory.put("endAddressDetail", hktsCargo.getEndAddressDetail());
        unloadHistory.put("regionCode", endAreaStr);
        unloadHistory.put("endTitle", hktsCargo.getEndTitle());
        saveUnload(unloadHistory);
        if (StringUtils.isNotBlank(hktsCargoTo.getRemark())){
            saveRemark(hktsCargoTo.getRemark());
        }
        if (hktsCargoTo.getAppoint() == null || hktsCargoTo.getAppoint().equals("")){
            hktsCargo.setAppoint(0);
        }
        frontInterface.saveGargoInformation(hktsCargo.getCargoName());
        return ResultUtil.data(hktsCargo);
    }

    public void saveLoadingHistory(Map<String, String> map) {
        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        List<Object> name = redisTemplate.opsForList().range(HistoryProperties.CARGO_HISTORY_LOADING + hontUserTo.getId(), 0, -1);
        if (name == null || name.size() == 0) {
            redisTemplate.opsForList().leftPush(HistoryProperties.CARGO_HISTORY_LOADING + hontUserTo.getId(), map);
        } else {
            redisTemplate.delete(HistoryProperties.CARGO_HISTORY_LOADING + hontUserTo.getId());
            if (name.contains(map)) {
                name.remove(map);
            }
            Collections.reverse(name);
            if (name.size() >= 10) {
                name.remove(0);
            }
            name.add(map);
            redisTemplate.opsForList().leftPushAll(HistoryProperties.CARGO_HISTORY_LOADING + hontUserTo.getId(), name);
        }
    }

    public void saveUnload(Map<String, String> map) {
        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        List<Object> name = redisTemplate.opsForList().range(HistoryProperties.CARGO_HISTORY_UNLOAD + hontUserTo.getId(), 0, -1);
        if (name == null || name.size() == 0) {
            redisTemplate.opsForList().leftPush(HistoryProperties.CARGO_HISTORY_UNLOAD + hontUserTo.getId(), map);
        } else {
            redisTemplate.delete(HistoryProperties.CARGO_HISTORY_UNLOAD + hontUserTo.getId());
            if (name.contains(map)) {
                name.remove(map);
            }
            Collections.reverse(name);
            if (name.size() >= 10) {
                name.remove(0);
            }
            name.add(map);
            redisTemplate.opsForList().leftPushAll(HistoryProperties.CARGO_HISTORY_UNLOAD + hontUserTo.getId(), name);
        }
    }
    public void saveRemark(String remark) {
        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        List<Object> name = redisTemplate.opsForList().range(HistoryProperties.CARGO_HISTORY_REMARK + hontUserTo.getId(), 0, -1);
        if (name == null || name.size() == 0) {
            redisTemplate.opsForList().leftPush(HistoryProperties.CARGO_HISTORY_REMARK + hontUserTo.getId(), remark);
        } else {
            redisTemplate.delete(HistoryProperties.CARGO_HISTORY_REMARK + hontUserTo.getId());
            if (name.contains(remark)) {
                name.remove(remark);
            }
            Collections.reverse(name);
            if (name.size() >= 10) {
                name.remove(0);
            }
            name.add(remark);
            redisTemplate.opsForList().leftPushAll(HistoryProperties.CARGO_HISTORY_REMARK + hontUserTo.getId(), name);
        }
    }

    @Override
    public BigDecimal getDistance(String startArea, String endArea) {
        BigDecimal distanceByAdress = AddressUtils.getDistanceByAdress(startArea, endArea);
        return distanceByAdress;
    }


    /**
     * 编辑货源
     *
     * @param hktsCargoTo
     * @return
     */
    public Result updateCargoAndLabelAndDetail(HktsCargoTo hktsCargoTo) {
        HktsCargo hktsCargo = hktsCargoMapper.selectById(hktsCargoTo.getCargoId());
        hktsCargo.getId();
        Result<Object> result=  loadingTimeService.addLoadTime(hktsCargo.getId(),hktsCargoTo.getLoadingTime());
        if(!result.isSuccess()){
            return ResultUtil.error(result.getMessage());
        }

        String startAreaStr = hktsCargoTo.getStartArea();
        /*String startArea = frontInterface.getRegionName(startAreaStr).getResult();*/
        String endAreaStr = hktsCargoTo.getEndArea();
        /*String endArea = frontInterface.getRegionName(endAreaStr).getResult();*/

        ResultAreaPlace startPlace = new ResultAreaPlace();
        startPlace.setAddressCode(startAreaStr);
        startPlace.setAddress(hktsCargoTo.getStartAddress());
        Integer reginCodeStart = Integer.valueOf(startAreaStr);
        startPlace = regionConverUtil.regionCover(reginCodeStart, startPlace);
        String startArea = startPlace.getProvice() + startPlace.getCity() + startPlace.getCounty();

        ResultAreaPlace endPlace = new ResultAreaPlace();
        endPlace.setAddressCode(endAreaStr);
        endPlace.setAddress(hktsCargoTo.getEndAddress());
        Integer reginCodeEnd = Integer.valueOf(endAreaStr);
        endPlace = regionConverUtil.regionCover(reginCodeEnd, endPlace);
        String endArea = endPlace.getProvice() + endPlace.getCity() + endPlace.getCounty();
        /**
         * 装货地点
         */
        hktsCargo.setStartArea(startAreaStr);
        hktsCargo.setStartAddressDetail(hktsCargoTo.getStartAddress());
        hktsCargo.setStartTitle(hktsCargoTo.getStartTitle());
        String lonLat = AddressUtils.getLonLat(startArea + hktsCargoTo.getStartAddress());
        String lon = lonLat.substring(0, lonLat.indexOf(","));
        String lat = lonLat.substring(lon.length() + 1, lonLat.length());
        BigDecimal lonto = StringUtil.getbd(lon);
        BigDecimal latto = StringUtil.getbd(lat);
        hktsCargo.setStartLat(latto);
        hktsCargo.setStartLon(lonto);
        /**
         * 卸货地点
         */
        hktsCargo.setEndArea(endAreaStr);
        hktsCargo.setEndAddressDetail(hktsCargoTo.getEndAddress());
        hktsCargo.setStartTitle(hktsCargoTo.getStartTitle());
        String endlonLat = AddressUtils.getLonLat(endArea + hktsCargoTo.getEndAddress());
        String endlon = endlonLat.substring(0, endlonLat.indexOf(","));
        String endlat = endlonLat.substring(endlon.length() + 1, endlonLat.length());
        BigDecimal endlonto = StringUtil.getbd(endlon);
        BigDecimal endlatto = StringUtil.getbd(endlat);
        hktsCargo.setEndLat(endlatto);
        hktsCargo.setEndLon(endlonto);
        String lonLatT = AddressUtils.getLonLat(hktsCargoTo.getStartAddress());
        String endlonLatT = AddressUtils.getLonLat(hktsCargoTo.getEndAddress());
        if (StringUtils.isBlank(lonLatT) && StringUtils.isBlank(endlonLatT)){
            return ResultUtil.error("请填写正确的装卸货地址");
        }
        /**
         * 重量、装货时间、是否邮寄回单、价格、发布时间、单位、剩余重量、用户姓名、电话、状态
         */
        BigDecimal transportPrice = StringUtil.getbd(hktsCargoTo.getTransportPrice());
        //如果修改总重量：判断
        if (hktsCargoTo.getCargoTotal().compareTo(hktsCargo.getCargoTotal()) > -1) {

            BigDecimal subtract = hktsCargoTo.getCargoTotal().subtract(hktsCargo.getCargoTotal());
            BigDecimal add = hktsCargo.getCargoResidual().add(subtract);
            hktsCargo.setCargoTotal(hktsCargoTo.getCargoTotal());
            hktsCargo.setCargoResidual(add);
        } else {
            if (hktsCargoTo.getCargoTotal().compareTo(hktsCargo.getCargoTotal().subtract(hktsCargo.getCargoResidual())) == -1) {
                return ResultUtil.error("总重量小于已接单数量，请重新输入");
            }else {

                BigDecimal subtract = hktsCargo.getCargoTotal().subtract(hktsCargoTo.getCargoTotal());
                BigDecimal add = hktsCargo.getCargoResidual().subtract(subtract);
                hktsCargo.setCargoTotal(hktsCargoTo.getCargoTotal());
                hktsCargo.setCargoResidual(add);
            }
        }

        hktsCargo.setIsReceipt(Integer.parseInt(hktsCargoTo.getIsReceipt()));
        hktsCargo.setTransportPrice(transportPrice);
        hktsCargo.setCargoName(hktsCargoTo.getCargoName());
        hktsCargo.setOrderType(hktsCargoTo.getOrderType());
        hktsCargo.setYbOrderCode(hktsCargoTo.getYbOrderCode());
        if (StringUtils.isBlank(hktsCargoTo.getCargoType())){
            return ResultUtil.error("请选择货物类型");
        }else {
            hktsCargo.setCargoType(hktsCargoTo.getCargoType());
        }
        hktsCargoMapper.updateCargoById(hktsCargo);

        /**
         * 货物信息
         */
        if (!hktsCargoTo.getLabelinfo().isEmpty()) {

            QueryWrapper<HktsCargoLabel> query = Wrappers.query();
            query.lambda().eq(HktsCargoLabel::getCargoId, hktsCargo.getId());
            labelMapper.delete(query);
            for (int i = 0; i < hktsCargoTo.getLabelinfo().size(); i++) {
                Integer type = hktsCargoTo.getLabelinfo().get(i).getType();
                List<String> values = hktsCargoTo.getLabelinfo().get(i).getValues();
                for (int j = 0; j < values.size(); j++) {
                    HktsCargoLabel cargoLabel = new HktsCargoLabel();
                    cargoLabel.setCargoId(hktsCargo.getId());
                    cargoLabel.setLabelType(type);
                    cargoLabel.setLabelName(values.get(j));
                    if (type == 4) {
                        cargoLabel.setLabelUnit("米");
                    }
                    cargoLabel.setUpdateTime(LocalDateTime.now());
                    labelMapper.insert(cargoLabel);
                }
            }
        }
        QueryWrapper<HktsCargoDetail> query = Wrappers.query();
        query.lambda().eq(HktsCargoDetail::getCargoId, hktsCargoTo.getCargoId());
        HktsCargoDetail cargoDetail = cargoDetailMapper.selectOne(query);
        if(hktsCargoTo.getDistance() == null ){
            BigDecimal distance = getDistance(startArea + hktsCargoTo.getStartAddress(), endArea + hktsCargoTo.getEndAddress());
            cargoDetail.setEstimateDistance(distance);
        }else {
            cargoDetail.setEstimateDistance(hktsCargoTo.getDistance());
        }
        cargoDetail.setUpdateTime(LocalDateTime.now());
        cargoDetail.setRemark(hktsCargoTo.getRemark());
        cargoDetail.setDeposit(hktsCargoTo.getDeposit());
        cargoDetailMapper.updateCargoDetailById(cargoDetail);
        Map<String, String> loadingHistory = new HashMap<>();
        loadingHistory.put("startArea", startArea);
        loadingHistory.put("startAddressDetail", hktsCargo.getStartAddressDetail());
        loadingHistory.put("regionCode", startAreaStr);
        saveLoadingHistory(loadingHistory);
        Map<String, String> unloadHistory = new HashMap<>();
        unloadHistory.put("endArea", endArea);
        unloadHistory.put("endAddressDetail", hktsCargo.getEndAddressDetail());
        unloadHistory.put("regionCode", endAreaStr);
        saveUnload(unloadHistory);
        saveRemark(hktsCargoTo.getRemark());
        return ResultUtil.data(hktsCargo);

    }

    /**
     * 关闭货源
     *
     * @param cargoId
     */
    @Override
    public void updateCagoStatus(String cargoId) {

        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        HktsCargo hktsCargo = hktsCargoMapper.selectById(cargoId);
        hktsCargo.setCargoStatus(1);
        hktsCargoMapper.updateCargoById(hktsCargo);

        List<HktsOrder> orderByCargoIdOnStatus = orderService.getOrderByCargoIdOnStatus(cargoId);
        orderMapper.updateByCargoId(cargoId,LocalDateTime.now());
        String format = "YYYY-MM-dd hh:mm:ss";
        for (int i = 0; i < orderByCargoIdOnStatus.size(); i++) {
            String id = orderByCargoIdOnStatus.get(i).getId();
            contractMapper.updateContractByOrderId(id);
            HktsCargoApply hktsCargoApply = cargoApplyMapper.selectById(orderByCargoIdOnStatus.get(i).getApplyId());

            if (hktsCargoApply.getDepositStatus() == PayConstants.PAID) {
                hktsCargoApply.setDepositStatus(PayConstants.REFUND);
                hktsCargoApply.setCheckStatus(PayConstants.AUDIT_FAILED);
                hktsCargoApply.setUpdateTime(LocalDateTime.now());
                cargoApplyMapper.updateApplyById(hktsCargoApply);
                iHktsReturnFailService.returnFee(hktsCargoApply);
            }else {
                cargoApplyMapper.updateByCargoId(hktsCargoApply.getId(),hontUserTo.getNickName(),PayConstants.AUDIT_FAILED,hktsCargoApply.getDepositStatus(),LocalDateTime.now().format(DateTimeFormatter.ofPattern(format)));
            }

            //TODO es同步数据
            orderService.updateOrderOnEs(id, OrderTypeEnum.CANCEL, OrderStatusEnum.OWNER_CANCEL.getValue());
        }
        //同步es数据
        Map<String,Object> map= esSearchUtil.getEsDateById(CARGO_ORDER_INDEX,cargoId);
        if(map==null||Integer.parseInt(map.get("count").toString())==0) {
            log.error("关闭货源，es查询数据为空{}", map);

        }else{
            Map<String, Object> cargoEsData = new ConcurrentHashMap<>(1);
            cargoEsData.put(CARGO_STATUS,1);
            //TODO es同步数据
            esSearchUtil.updateToEs(cargoEsData,CARGO_ORDER_INDEX,cargoId);
        }
    }

    /**
     * 货源列表
     * @param page
     * @param pcCargoDTO
     * @return
     */
    public IPage<ResultData> getHktsCargoPageListOnPhonePc(Page page, PcCargoDTO pcCargoDTO){

        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        QueryWrapper<HktsCargo> query = Wrappers.query();
        //条件
        if (pcCargoDTO.getCargoStatus() != null){
            query.eq("cargo_status", pcCargoDTO.getCargoStatus());
        }
        if (hontUserTo.getCompanyId() != null){
            query.eq("company_code", hontUserTo.getCompanyId());
        }
        if (StringUtils.isNotEmpty(pcCargoDTO.getStartPlace())){
            query.like("start_address_detail",pcCargoDTO.getStartPlace());
        }
        if (StringUtils.isNotEmpty(pcCargoDTO.getEndPlace())){
            query.like("end_address_detail",pcCargoDTO.getEndPlace());
        }
        if (StringUtils.isNotEmpty(pcCargoDTO.getUserName())){
            query.like("username",pcCargoDTO.getUserName());
        }
        if (StringUtils.isNotEmpty(pcCargoDTO.getMobile())){
            query.like("telphone",pcCargoDTO.getMobile());
        }
        if (StringUtils.isNotEmpty(pcCargoDTO.getCargoName())){
            query.like("cargo_name",pcCargoDTO.getCargoName());
        }
        query.apply(!"".equals(pcCargoDTO.getStartDate()),
                        "date_format (push_time,'%Y-%m-%d') >= date_format('" + pcCargoDTO.getStartDate() + "','%Y-%m-%d')")
                .apply(!"".equals(pcCargoDTO.getEndDate()),
                        "date_format (push_time,'%Y-%m-%d') <= date_format('" + pcCargoDTO.getEndDate() + "','%Y-%m-%d')");
        query.orderByDesc("push_time");
        IPage page1 = hktsCargoMapper.selectPage(page, query);
        List<HktsCargo> list = page1.getRecords();
        List<Map<String,Object>> resultDate = list.stream().map(this::assemblyCargoDataPc).collect(Collectors.toList());
        for (int i = 0; i < resultDate.size(); i++) {
            resultDate.get(i).put("serialnumber",page1.getCurrent() * page1.getSize() - page1.getSize() + i + 1);
        }
        page1.setRecords(resultDate);
        return page1;
    }

    public Map<String,Object> assemblyCargoDataPc(HktsCargo hktsCargo){
        Map<String,Object> resultMap = new HashMap<>();
        ResultData hktsCargoVo = new ResultData();
        hktsCargoVo = assemblyAreaPlace(hktsCargo, hktsCargoVo);
        HktsCargoDetail cargoDetail=cargoDetailService.getHktsCargoDetailByCargoId(hktsCargo.getId());
        resultMap.put("id",hktsCargo.getId());
        resultMap.put(CargoListVoConstants.START_PLACE,hktsCargoVo.getStartPlace());
        resultMap.put(CargoListVoConstants.END_PLACE,hktsCargoVo.getEndPlace());
        resultMap.put("username","姓名：" + hktsCargo.getUsername());
        resultMap.put("mobile","手机：" + hktsCargo.getTelphone());
        resultMap.put(CargoListVoConstants.CARGONAME,hktsCargo.getCargoName());
        resultMap.put(CargoListVoConstants.PUSHTIME,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(hktsCargo.getPushTime()));
        resultMap.put(CargoListVoConstants.TRANSPORTPRICE,hktsCargo.getTransportPrice());
        resultMap.put(CargoListVoConstants.CARGORESIDUAL,hktsCargo.getCargoResidual() + "/" + hktsCargo.getCargoTotal());
        resultMap.put("cargoStatus",hktsCargo.getCargoStatus());
        resultMap.put("appoint",hktsCargo.getAppoint());
        resultMap.put(CargoListVoConstants.CARTYPE, labelService.getCargoLanelByCargoId(hktsCargo.getId(), 3));
        resultMap.put(CargoListVoConstants.CARLENGTH, labelService.getCargoLanelByCargoId(hktsCargo.getId(), 4));
        if (cargoDetail.getDeposit() == null){
            resultMap.put(CargoDetailsVoConstants.DEPOSIT,"");
        }else {
            resultMap.put(CargoDetailsVoConstants.DEPOSIT,cargoDetail.getDeposit());
        }

        HktsCargoApply hktsCargoApply = new HktsCargoApply();
        hktsCargoApply.setCargoId(hktsCargo.getId());
        resultMap.put(CargoDetailsVoConstants.APPLY, applyService.selectCount(hktsCargoApply));
        // TODO 已查看人数统计
        int viewRecordCount = cargoViewRecordService.getViewRecordCount(hktsCargo.getId());
        resultMap.put("viewRecordCount", viewRecordCount);
        return resultMap;
    }



    public IPage<Map<String, Object>> getOrderPageListByCargoId(Page page,String cargoId,String orderStatus){
        QueryWrapper<HktsOrder> query = Wrappers.query();
        query.lambda().eq(HktsOrder::getCargoId, cargoId).eq(StringUtils.isNotBlank(orderStatus) && !orderStatus.equals("ALL"),HktsOrder::getOrderStatus,orderStatus);
        Page page1 = orderMapper.selectPage(page,query);

        List<HktsOrder> list = page1.getRecords();
        List<Map<String, Object>> result = list.stream().map(t -> resultOrderPageListByCargoId(t)).collect(Collectors.toList());
        for (int i = 0; i < result.size(); i++) {
            result.get(i).put("serialnumber",page1.getCurrent() * page1.getSize() - page1.getSize() + i + 1);
        }
        page1.setRecords(result);
        return page1;
    }

    public Map<String, Object> resultOrderPageListByCargoId(HktsOrder hktsOrder){

        HktsCargo hktsCargo = hktsCargoMapper.selectById(hktsOrder.getCargoId());
        HktsCargoApply hktsCargoApply = cargoApplyMapper.selectById(hktsOrder.getApplyId());
        QueryWrapper<HktsContract> query = Wrappers.query();
        query.lambda().eq(HktsContract::getOrderId,hktsOrder.getId());
        HktsContract hktsContract = contractMapper.selectOne(query);
        Result<UserAndRealNameVo> driverInfoByUserId = frontInterface.getDriverInfoByUserId(hktsOrder.getDriverId());
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put(OrderVoConstants.ORDERCODE,hktsOrder.getId());
        resultMap.put("driverName",driverInfoByUserId.getResult().getDriverName());
        resultMap.put("mobile",driverInfoByUserId.getResult().getMobile());
        resultMap.put("carCode",driverInfoByUserId.getResult().getCarCode());
        resultMap.put(CargoListVoConstants.CARGONAME,hktsCargo.getCargoName());
        resultMap.put(CargoListVoConstants.CARGOWEIGHT,hktsContract.getCargoWeight());
        resultMap.put("createTime",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(hktsOrder.getCreateTime()));
        resultMap.put("id",hktsOrder.getId());
        resultMap.put("orderStatus",hktsOrder.getOrderStatus());
        resultMap.put("checkStatus",hktsCargoApply.getCheckStatus());
        return resultMap;
    }

    public Map<String,Object> getApplyCountAndWeight(String cargoId){
        HktsCargo hktsCargo = hktsCargoMapper.selectById(cargoId);
        Map<String,Object> resultMap = new HashMap<>();
        HktsCargoApply hktsCargoApply = new HktsCargoApply();
        hktsCargoApply.setCargoId(cargoId);
        resultMap.put(CargoDetailsVoConstants.APPLY, applyService.selectCount(hktsCargoApply));
        int viewRecordCount = cargoViewRecordService.getViewRecordCount(cargoId);
        resultMap.put("viewRecordCount", viewRecordCount);
        resultMap.put(CargoListVoConstants.CARGORESIDUAL,hktsCargo.getCargoResidual() + "/" + hktsCargo.getCargoTotal());
        ResultData hktsCargoVo = new ResultData();
        hktsCargoVo = assemblyAreaPlace(hktsCargo, hktsCargoVo);
        resultMap.put(CargoListVoConstants.START_PLACE,hktsCargoVo.getStartPlace());
        resultMap.put(CargoListVoConstants.END_PLACE,hktsCargoVo.getEndPlace());
        return resultMap;
    }

    @Override
    public List<Map<String, Object>> selectListByTitle(){


        List<Map<String, Object>> maps = hktsCargoMapper.selectByTitle();
        List<Map<String, Object>> collect = maps.stream().map(t -> resultCargoPageListByRegion(t)).collect(Collectors.toList());
        return collect;
    }


    public Map<String, Object> resultCargoPageListByRegion(Map<String, Object> map){

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        ResultAreaPlace startPlace = new ResultAreaPlace();
        startPlace.setAddressCode(map.get("start_area").toString());
        startPlace.setAddress(map.get("start_address_detail").toString());
        Integer reginCodeStart = Integer.valueOf(map.get("start_area").toString());
        startPlace = regionConverUtil.regionCover(reginCodeStart, startPlace);

        ResultAreaPlace endPlace = new ResultAreaPlace();
        endPlace.setAddressCode(map.get("end_area").toString());
        endPlace.setAddress(map.get("end_address_detail").toString());
        Integer reginCodeEnd = Integer.valueOf(map.get("end_area").toString());
        endPlace = regionConverUtil.regionCover(reginCodeEnd, endPlace);

        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("start_area",startPlace.getProvice());
        resultMap.put("end_area",endPlace.getProvice());
        resultMap.put("end_address_detail",map.get("end_address_detail").toString());
        resultMap.put("start_address_detail",map.get("start_address_detail").toString());
        resultMap.put("id",map.get("id").toString());
        Result<Map<String, Object>> start_address_detail = frontInterface.getQqsData(resultMap.get("start_address_detail").toString(), resultMap.get("start_area").toString());

        List<Map<String, Object>> startData = (List<Map<String, Object>>) start_address_detail.getResult().get("data");

        if (startData.size()>0){
            resultMap.put("start_title",startData.get(0).get("title"));
            resultMap.put("start_address",startData.get(0).get("address"));
        }else {
            resultMap.put("start_title","");
            resultMap.put("start_address","");
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Result<Map<String, Object>> end_address_detail = frontInterface.getQqsData(resultMap.get("end_address_detail").toString(), resultMap.get("end_area").toString());
        List<Map<String, Object>> endData = (List<Map<String, Object>>) end_address_detail.getResult().get("data");
        if (endData.size()>0){
            resultMap.put("end_title",endData.get(0).get("title"));
            resultMap.put("end_address",startData.get(0).get("address"));
        }else {
            resultMap.put("end_title","");
            resultMap.put("end_address","");
        }

        hktsCargoMapper.updateCargoTitleById(resultMap.get("start_title").toString(),resultMap.get("start_title").toString(),resultMap.get("id").toString());
        orderMapper.updateOrderAddressById(resultMap.get("start_address").toString(),resultMap.get("end_address").toString(),resultMap.get("id").toString());
        return resultMap;
    }
    @Override
    public Map<String,Object> getOrderData(String cargoId){
        HktsCargo hktsCargo = hktsCargoMapper.selectById(cargoId);
        if (hktsCargo.getYbOrderCode() == null || hktsCargo.getYbOrderCode().equals("")){
            return new HashMap<>();
        }
        Map<String,Object> resultMap = new HashMap<>();
        if (hktsCargo.getOrderType() == 2){
            Result<Map<String,Object>> objectResult = ybInterface.selectPovouchListBycInvName(hktsCargo.getYbOrderCode());
            resultMap.put("orderCode",objectResult.getResult().get("cPOID"));
            resultMap.put("providerOrClient",objectResult.getResult().get("cVenAbbName"));
            resultMap.put("cInvName",objectResult.getResult().get("cInvName"));
            resultMap.put("estimatedShipDate",objectResult.getResult().get("dmodifyTime"));
            resultMap.put("model",objectResult.getResult().get("cInvStd"));
            resultMap.put("orderQuantity",objectResult.getResult().get("iQuantity"));
            resultMap.put("noOrAddUp","");
            resultMap.put("orderType",hktsCargo.getOrderType());
            return resultMap;
        }else{
            Result<Map<String, Object>> mapResult = ybInterface.selectSovouchListBycInvName(hktsCargo.getYbOrderCode());
            resultMap.put("orderCode",mapResult.getResult().get("cSOCode"));
            resultMap.put("providerOrClient",mapResult.getResult().get("cCusAbbName"));
            resultMap.put("cInvName",mapResult.getResult().get("cInvName"));
            resultMap.put("estimatedShipDate",mapResult.getResult().get("dmodifyTime"));
            resultMap.put("model",mapResult.getResult().get("cInvStd"));
            resultMap.put("orderQuantity",mapResult.getResult().get("iQuantity"));
            resultMap.put("noOrAddUp","");
            resultMap.put("orderType",hktsCargo.getOrderType());
            return resultMap;
        }
    }
}
